/******************************************************************************

                           UART SOURCE FILE

 *******************************************************************************/
/**********************************************************************
* � 2009 Microchip Technology Inc.
*
* FileName:        uart.c
* Dependencies:    Header (.h) files if applicable, see below
* Processor:       PIC32
* Compiler:        MPLAB� C32
*
* SOFTWARE LICENSE AGREEMENT:
* Microchip Technology Incorporated ("Microchip") retains all ownership and
* intellectual property rights in the code accompanying this message and in all
* derivatives hereto.  You may use this code, and any derivatives created by
* any person or entity by or on your behalf, exclusively with Microchip's
* proprietary products.  Your acceptance and/or use of this code constitutes
* agreement to the terms and conditions of this notice.
*
* CODE ACCOMPANYING THIS MESSAGE IS SUPPLIED BY MICROCHIP "AS IS".  NO
* WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS CODE, ITS INTERACTION WITH MICROCHIP'S
* PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
*
* YOU ACKNOWLEDGE AND AGREE THAT, IN NO EVENT, SHALL MICROCHIP BE LIABLE, WHETHER
* IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY),
* STRICT LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL,
* PUNITIVE, EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF
* ANY KIND WHATSOEVER RELATED TO THE CODE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN
* ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT
* ALLOWABLE BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO
* THIS CODE, SHALL NOT EXCEED THE PRICE YOU PAID DIRECTLY TO MICROCHIP SPECIFICALLY TO
* HAVE THIS CODE DEVELOPED.
*
* You agree that you are solely responsible for testing the code and
* determining its suitability.  Microchip has no obligation to modify, test,
* certify, or support the code.
************************************************************************/

#include <plib.h>					// Peripheral Library
#include "HardwareProfile.h"
#include "stdio.h"
#include "stdarg.h"
#include "string.h"
#include "uart.h"
#define DESIRED_BAUDRATE    	(115200)      //The desired BaudRate

BYTE data_received;
BOOL byte_received;

/*
********************************************************************************
* Function name 	: WriteString
* Input Parameters	: String
* Return Type		: None
* Functionality		: Prints a string through UART
********************************************************************************
*/

void WriteString(const CHAR *string)
{
    while(*string != '\0')
    {
        while(!UARTTransmitterIsReady(UART1));

        UARTSendDataByte(UART1, *string);

        string++;

        while(!UARTTransmissionHasCompleted(UART1));

    }
}
/*
********************************************************************************
* Function name 	: PutCharacter
* Input Parameters	: Character
* Return Type		: None
* Functionality		: Prints character by character through UART
********************************************************************************
*/

void PutCharacter(const CHAR character)
{
    while(!UARTTransmitterIsReady(UART1))
        ;
    data_received = character;
    UARTSendDataByte(UART1, character);

    while(!UARTTransmissionHasCompleted(UART1))
        ;
}

/*
********************************************************************************
* Function name 	: printString
* Input Parameters	: Address Pointer to the string
* Return Type		: None
* Functionality		: Prints a formatted data on the UART port
********************************************************************************
*/
void  printString (const  BYTE *format, ...)
{
    static CHAR  buffer[100];
    va_list  vArgs;

    memset(buffer, 0, 100);
    va_start(vArgs, format);
    vsprintf((char *)buffer, (char const *)format, vArgs);
    va_end(vArgs);

    WriteString(buffer);
}
/*
******************************************************************************
* Function name 	: InitUart
* Input Parameters	: None
* Return Type		: None
* Functionality		: Initializes UART
******************************************************************************
*/

void InitUart(BYTE uart_num)
{

	// Configure the device for maximum performance but do not change the PBDIV
	// Given the options, this function will change the flash wait states, RAM
	// wait state and enable prefetch cache but will not change the PBDIV.
	// The PBDIV value is already set via the pragma FPBDIV option above..
	SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

	mPORTDClearBits(BIT_0); 		// Turn off RA7 on startup.
	mPORTDSetPinsDigitalOut(BIT_0);	// Make RA7 as output.


	// Explorer-16 uses UART2 to connect to the PC.
	// This initialization assumes 36MHz Fpb clock. If it changes,
	// you will have to modify baud rate initializer.

    UARTConfigure(uart_num, UART_ENABLE_PINS_TX_RX_ONLY);
    UARTSetFifoMode(uart_num,UART_INTERRUPT_ON_TX_NOT_FULL |UART_INTERRUPT_ON_RX_NOT_EMPTY);
    UARTSetLineControl(uart_num, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
    UARTSetDataRate(uart_num, GetPeripheralClock(), DESIRED_BAUDRATE);
    UARTEnable(uart_num, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));

	// Configure UART2 RX Interrupt
    INTEnable(INT_SOURCE_UART_RX(uart_num), INT_ENABLED);
    INTSetVectorPriority(INT_VECTOR_UART(uart_num), INT_PRIORITY_LEVEL_2);
    INTSetVectorSubPriority(INT_VECTOR_UART(uart_num), INT_SUB_PRIORITY_LEVEL_0);
    UART_Print("Initialized UART TX\r\n");
}


/*
******************************************************************************
* Function name 	: IntUart1Handler
* Input Parameters	: None
* Return Type		: None
* Functionality		: Handles UART interrupt
******************************************************************************
*/
// UART 2 interrupt handler
// it is set at priority level 2
void __ISR(_UART1_VECTOR, ipl2) IntUart1Handler(void)
{
    // Is this an RX interrupt?
    if(INTGetFlag(INT_SOURCE_UART_RX(UART1)))
    {
        //mU1ARXClearIntFlag();
        UARTGetDataByte(UART1);
        // Clear the RX interrupt Flag
        INTClearFlag(INT_SOURCE_UART_RX(UART1));

        // Echo what we just received.
        //PutCharacter(UARTGetDataByte(UART1));

        //UART_Print("inside ISR RX\r\n");

        // Toggle LED to indicate UART activity
        mPORTDToggleBits(BIT_0);
       
    }
    INTClearFlag(INT_SOURCE_UART_TX(UART1));
    // We don't care about TX interrupt
    if ( INTGetFlag(INT_SOURCE_UART_TX(UART1)) )
    {
      //  UART_Print("inside ISR TX\r\n");
        INTClearFlag(INT_SOURCE_UART_TX(UART1));
    }
}

void __ISR(_UART2_VECTOR, ipl3) IntUart2Handler(void)
{
    //UART_Print("Inside ISR\r\n");
	// Is this an RX interrupt?

	if(INTGetFlag(INT_SOURCE_UART_RX(UART2)))
	{//UART_Print("Inside ISR2\r\n");
            PutCharacter(UARTGetDataByte(UART2));
		// Clear the RX interrupt Flag
	    INTClearFlag(INT_SOURCE_UART_RX(UART2));

		// Echo what we just received.

                //INTClearFlag(INT_SOURCE_UART_TX(UART1));

		// Toggle LED to indicate UART activity
		//mPORTDToggleBits(BIT_0);
            byte_received = TRUE;

	}


	// We don't care about TX interrupt
	if ( INTGetFlag(INT_SOURCE_UART_TX(UART2)) )
	{
		INTClearFlag(INT_SOURCE_UART_TX(UART2));
	}
}
